﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.XPath;
using System.Xml;
using FinanSoft.Entities;
using FinanSoft.Utilities;
using System.Collections.ObjectModel;
using FinanSoft.DataLayer;

namespace FinanSoft.BusinessLayer
{
    class DocumentManager
    {
        #region Atributes
    
        private Document _Document;
        private bool _isError;
        private String _errorMessage;
        #endregion

        #region Properties
        public bool IsError
        {
            get
            {
                return _isError;
            }
        }

        public String ErrorMessage
        {
            get
            {
                return _errorMessage;
            }
        }
        #endregion

        #region Singleton


        private DocumentManager()
        {
            _isError = false;
            _errorMessage = "";            
        }

        /// <summary>
        /// Única instancia de esta clase
        /// </summary>
        private static DocumentManager _instance;

        /// <summary>
        /// Método para implementar el patrón de Singleton
        /// </summary>
        /// <returns>Instancia única de la clase</returns>
        public static DocumentManager GetInstance()
        {
            if (_instance == null)
                _instance = new DocumentManager();
            return _instance;
        }
        #endregion

        #region Métodos

        /// <summary>
        /// Método que se encarga de inicializar las de Cuentas Especiales asignadas como de tipo
        /// de la cuenta especial seleccionada
        /// </summary>
        /// <returns>Retorna el objeto cuenta especial con todas cuentas de un tipo especial</returns>
        public Document GetDoc(int idDocumentoContable)
        {
            //Se obtiene el encabezado del documento
            _Document = DocumentDataManager.GetInstance().GetDocEncabezado(idDocumentoContable);
            
            //Se obtiene el detalle del documento
            _Document.detalleDoc = DocumentDataManager.GetInstance().GetDocumentDetails(idDocumentoContable).ToArray();

            //Se calculan los montos del docuemento
            _Document.subTotal = CalcularSubtotal(_Document.detalleDoc);
            _Document.impuestos = 0;
            foreach (DocDetail detail in _Document.detalleDoc)
                _Document.impuestos += detail.UnitCost * detail.Quantity * ConfigurationManager.GetInstance().GetTax(detail.Tax.IdImpuesto).Porcentaje;
            _Document.total = _Document.impuestos + _Document.subTotal;
            return _Document;
        }

        /// <summary>
        /// Devuelve todas las lineas del documento con el id dado.
        /// </summary>
        /// <param name="docId"></param>
        /// <returns></returns>
        public List<DocDetail> GetDocumentDetails(int docId)
        {
            return DocumentDataManager.GetInstance().GetDocumentDetails(docId);
        }

        /// <summary>
        /// Recupera todos los servicios asociados a un documento (factura a cliente o nota de crédito de servicios)
        /// </summary>
        /// <param name="doc"></param>
        /// <returns></returns>
        public List<DocService> GetDocumentServices(Document doc)
        {
            return DocumentDataManager.GetInstance().GetDocumentServices(doc);
        }

        /// <summary>
        /// Calcula el subtotal del documento, calculado cant * precio para cada item
        /// </summary>
        /// <param name="detalleDoc"> Recibe la lista de items del documento </param>
        /// <returns> el subtotal del documento</returns>
        public double CalcularSubtotal(DocDetail[] detalleDoc)
        {
            double _subtotal = 0;
            for (int i = 0; i < detalleDoc.Length; i++)
            {
                _subtotal = _subtotal + (detalleDoc[i].Quantity * detalleDoc[i].UnitCost);
            }

            return _subtotal;
        }
        
        /// <summary>
        /// Calcula el total del documento, restandole al subtotal los impuestos y descuentos.
        /// </summary>
        /// <param name="_porcentajeDescuento"></param>
        /// <param name="_montoImp"></param>
        /// <param name="_subtotal"></param>
        /// <returns></returns>
        public double CalcularTotal(double _porcentajeDescuento, double _montoImp, double _subtotal)
        {
            double _total = 0;
            double _montoDesc = 0;

            _montoDesc = _subtotal * (_porcentajeDescuento / 100);

            _total = _subtotal - _montoDesc - _montoImp;

            return _subtotal;
        }

        #endregion
    }
}
